package net.web.service.impl;

import net.web.common.utils.PageInfo;
import net.web.dao.UserDao;
import net.web.entity.User;
import net.web.service.UserService;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.security.MessageDigest;
import java.util.Base64;
import java.util.List;
import java.util.Random;
import javax.imageio.ImageIO;

public class UserServiceImpl implements UserService {

    private UserDao userDao = new UserDao();

    @Override
    public PageInfo<User> pageList(int pageNo, int pageSize, User user) {
        return userDao.pagelist(pageNo, pageSize, user);
    }

    @Override
    public List<User> list() {
        return userDao.list();
    }

    @Override
    public boolean insert(User user) {
        return userDao.insert(user);
    }

    @Override
    public boolean delete(int id) {
        return userDao.delete(id);
    }

    @Override
    public boolean update(User user) {
        return userDao.update(user);
    }

    @Override
    public boolean updateProfile(User user) {
        return userDao.updateProfile(user);
    }

    @Override
    public boolean updatePassword(int userId, String oldPassword, String newPassword) {
        User user = userDao.findById(userId);
        if (user == null) {
            return false;
        }

        String hashedOldPassword = hashPassword(oldPassword);
        if (!hashedOldPassword.equals(user.getPassword())) {
            return false;
        }

        String hashedNewPassword = hashPassword(newPassword);
        return userDao.updatePassword(userId, hashedNewPassword);
    }

    @Override
    public User findById(int id) {
        return userDao.findById(id);
    }

    @Override
    public User findByUsername(String username) {
        return userDao.findByUsername(username);
    }

    @Override
    public User findByEmail(String email) {
        return userDao.findByEmail(email);
    }

    @Override
    public User findByUsernameOrEmail(String loginName) {
        return userDao.findByUsernameOrEmail(loginName);
    }

    @Override
    public boolean register(User user) {
        if (existsByUsername(user.getUsername()) || existsByEmail(user.getEmail())) {
            return false;
        }

        user.setPassword(hashPassword(user.getPassword()));
        user.setRole(0);
        user.setUserPicture("");

        return userDao.insert(user);
    }

    @Override
    public User login(String loginName, String password) {
        User user = userDao.findByUsernameOrEmail(loginName);
        if (user == null) {
            return null;
        }

        String hashedPassword = hashPassword(password);
        if (hashedPassword.equals(user.getPassword())) {
            user.setPassword(null);
            return user;
        }

        return null;
    }

    @Override
    public boolean existsByUsername(String username) {
        return userDao.existsByUsername(username);
    }

    @Override
    public boolean existsByEmail(String email) {
        return userDao.existsByEmail(email);
    }

    @Override
    public boolean existsByUsernameExcludeId(String username, int excludeId) {
        return userDao.existsByUsernameExcludeId(username, excludeId);
    }

    @Override
    public boolean existsByEmailExcludeId(String email, int excludeId) {
        return userDao.existsByEmailExcludeId(email, excludeId);
    }

    @Override
    public String generateAvatar(String username, int size) {
        try {
            if (size > 64) size = 64;

            BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = image.createGraphics();

            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            Color[] colors = {
                new Color(255, 207, 210), new Color(180, 250, 228), new Color(163, 196, 243),
                new Color(205, 180, 219), new Color(253, 228, 207), new Color(248, 249, 250)
            };

            Random random = new Random(username.hashCode());
            Color bgColor = colors[random.nextInt(colors.length)];
            g2d.setColor(bgColor);
            g2d.fillRect(0, 0, size, size);

            g2d.setColor(new Color(73, 80, 87));
            g2d.setFont(new Font("Arial", Font.BOLD, size / 2));

            String initial = username.substring(0, 1).toUpperCase();
            FontMetrics fm = g2d.getFontMetrics();
            int x = (size - fm.stringWidth(initial)) / 2;
            int y = ((size - fm.getHeight()) / 2) + fm.getAscent();
            g2d.drawString(initial, x, y);

            g2d.dispose();

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(image, "PNG", baos);
            byte[] imageBytes = baos.toByteArray();

            return "data:image/png;base64," + Base64.getEncoder().encodeToString(imageBytes);
        } catch (Exception e) {
            return "";
        }
    }

    private String hashPassword(String password) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hashedBytes = md.digest(password.getBytes("UTF-8"));
            StringBuilder sb = new StringBuilder();
            for (byte b : hashedBytes) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (Exception e) {
            return password;
        }
    }
}
